#include "register.h"
#include <iostream>

inline bool register_id_valid(int id) {
    // 逻辑问题？
    if (id >= VR0 && id <= CVCCR) {
        return true;
    } else {
        return false;
    }
}

inline bool register_id_isvec(int id) {
    if (id >= VR0 && id <= VR63) {
        return true;
    } else {
        return false;
    }
}

//通过该函数将寄存器下标进行转换，跳过enum开头的64个VR寄存器
//所有操作非向量寄存器的操作应当通过该函数进行下标转换
inline int reg_id2non_vec_id(int id) {
    return (id - VR_NUMS);
}

uint64_t RegisterFile::get_register_value(int id) {
    std::cout << "Getting register value for ID " << id << std::endl;
    if (register_id_valid(id)) {
        int new_id = reg_id2non_vec_id(id);
        std::cout << "<get reg> new id is " << std::dec <<new_id << std::endl;
        return this->register_value->at(new_id);
    } else {
        return 0;
    }
}

std::vector<uint64_t>* RegisterFile::get_vec_register_value(int id) {
    std::cout << "Getting vector register value for ID " << id << std::endl;
    if (register_id_valid(id)) {
        if (register_id_isvec(id)) {
            //头文件中的enum保证VR0从0开始编号
            return this->vec_reg_value->at(id);
        } else {
            return NULL;
        }
    } else {
        return NULL;
    }
}

bool RegisterFile::set_register_value(int id, uint64_t value) {
    if (register_id_valid(id)) {
        int new_id = reg_id2non_vec_id(id);
        std::cout << "<set reg> new id is " << std::dec << new_id << std::endl;
        this->register_value->at(new_id) = value;
        return true;
    } else {
        return false;
    }
}

bool RegisterFile::set_register_value(int id, std::vector<uint64_t>* value) {
    if (register_id_valid(id)) {
        if (register_id_isvec(id)) {
            //!!!BUG??? --- 此处在测试时注意，注意是否代码其他部分有错误释放指针导致dangling pointer的问题
            //2024.12.28 此处需要赋值，而不能赋指针
            //2025.02.23 此处采用赋指针的方式
            //!value这一指针无需caller负责释放
            //在进行新的赋值之前，由该部分代码负责释放旧的值（旧的指针），因为旧值将被覆盖，无需再使用
            //!!!BUG??? --- 此处在测试注意，注意是否代码其他部分在执行reg write之后，又对旧的reg值进行访问，dangling pointer
            delete this->vec_reg_value->at(id);
            this->vec_reg_value->at(id) = value;
            return true;
        } else {
            return false;
        }
    } else {
        return false;
    }
}

bool RegisterFile::set_vec_regsiter_single(int id, int index, uint64_t value) {
    if (register_id_valid(id)) {
        if (register_id_isvec(id)) {
            //此处需要赋值，而不能赋指针
            //!value这一指针在caller调用该函数返回后，将由caller负责delete value
            this->vec_reg_value->at(id)->at(index) = value;
            return true;
        } else {
            return false;
        }
    } else {
        return false;
    }
}